home *** CD-ROM | disk | FTP | other *** search
/ Amiga Developer CD 2.1 / Amiga Developer CD v2.1.iso / Reference / DevCon / Milan_1991 / Devcon91.4 / AdaptingToFonts / Example2.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-09-01  |  25.1 KB  |  861 lines

  1. /*
  2.  * Example 2 - Based on the UI code for FontMover 2.0 by Michael Sinz
  3.  *
  4.  * Copyright (c) 1989,90 - MKSoft Development
  5.  *
  6.  ************************************************************************
  7.  *                                                                      *
  8.  *                            DISCLAIMER                                *
  9.  *                                                                      *
  10.  *   THIS SOFTWARE IS PROVIDED "AS IS".                                 *
  11.  *   NO REPRESENTATIONS OR WARRANTIES ARE MADE WITH RESPECT TO THE      *
  12.  *   ACCURACY, RELIABILITY, PERFORMANCE, CURRENTNESS, OR OPERATION      *
  13.  *   OF THIS SOFTWARE, AND ALL USE IS AT YOUR OWN RISK.                 *
  14.  *   NEITHER COMMODORE NOR THE AUTHORS ASSUME ANY RESPONSIBILITY OR     *
  15.  *   LIABILITY WHATSOEVER WITH RESPECT TO YOUR USE OF THIS SOFTWARE.    *
  16.  *                                                                      *
  17.  ************************************************************************
  18.  */
  19.  
  20. #include    <exec/types.h>
  21. #include    <exec/lists.h>
  22. #include    <exec/nodes.h>
  23. #include    <exec/memory.h>
  24. #include    <exec/alerts.h>
  25. #include    <graphics/text.h>
  26. #include    <graphics/rastport.h>
  27. #include    <libraries/dos.h>
  28. #include    <intuition/intuition.h>
  29.  
  30. #include    <proto/intuition.h>
  31. #include    <proto/exec.h>
  32. #include    <proto/graphics.h>
  33. #include    <proto/layers.h>
  34.  
  35. #include    <string.h>
  36. #include    <ctype.h>
  37.  
  38. #include    "RenderInfo.h"
  39. #include    "Example2Strings.h"
  40.  
  41. struct    Library    *LayersBase;
  42.  
  43. /*
  44.  * Some code to fill in border arrays for boxes...
  45.  */
  46.  
  47. /*
  48.  * This function makes a top-left border array based on the
  49.  * x/y size of the box...
  50.  */
  51. VOID    FillTopLeft_Border(struct Border *bd,SHORT xSize,SHORT ySize)
  52. {
  53. register    SHORT    *xy;
  54.  
  55.     xy=bd->XY;
  56.     xy[0]=xSize-2;        xy[1]=0;
  57.     xy[2]=0;        xy[3]=0;
  58.     xy[4]=0;        xy[5]=ySize-1;
  59.     xy[6]=1;        xy[7]=ySize-2;
  60.     xy[8]=1;        xy[9]=1;
  61. }
  62.  
  63. /*
  64.  * This function makes a bottom-right border array based on the
  65.  * x/y size of the box...
  66.  */
  67. VOID    FillBottomRight_Border(struct Border *bd,SHORT xSize,SHORT ySize)
  68. {
  69. register    SHORT    *xy;
  70.  
  71.     xy=bd->XY;
  72.     xy[0]=1;        xy[1]=ySize-1;
  73.     xy[2]=xSize-1;        xy[3]=ySize-1;
  74.     xy[4]=xSize-1;        xy[5]=0;
  75.     xy[6]=xSize-2;        xy[7]=1;
  76.     xy[8]=xSize-2;        xy[9]=ySize-2;
  77. }
  78.  
  79. /*
  80.  * These are just STUB routines for a more complex gadget
  81.  * this is not part of the example but is used in the
  82.  * interface...
  83.  */
  84. struct DisplayList
  85. {
  86. struct    Gadget        Gadget;
  87. struct    Border        Borders[2*2];
  88.     SHORT        Vectors[2*5*2];
  89. };
  90.  
  91. /*
  92.  * This routine deallocates the DisplayList allocated below...
  93.  * It does not do any unlinking...
  94.  */
  95. void FreeListGadget(struct DisplayList *list)
  96. {
  97.     if (list) FreeMem(list,sizeof(struct DisplayList));
  98. }
  99.  
  100. /*
  101.  * This routine allocates and initializes a DisplayList gadget...
  102.  * It will link the gadgets into the gadget list given...
  103.  *
  104.  * Arguments:  **Gadget,Highlight,Shadow,Left,Top,Width,Height
  105.  */
  106. struct DisplayList *InitListGadget(struct Gadget **gad,UBYTE Highlight,UBYTE Shadow,SHORT Left,SHORT Top,SHORT Width,SHORT Height)
  107. {
  108. struct    DisplayList    *list;
  109.  
  110.     if (list=AllocMem(sizeof(struct DisplayList),MEMF_PUBLIC|MEMF_CLEAR))
  111.     {
  112.         /*
  113.          * Set up borders for the gadget
  114.          */
  115.         list->Borders[0].FrontPen=Highlight;
  116.         list->Borders[0].DrawMode=JAM1;
  117.         list->Borders[0].Count=5;
  118.         list->Borders[0].XY=&(list->Vectors[0*5*2]);
  119.         list->Borders[0].NextBorder=&(list->Borders[1]);
  120.  
  121.         list->Borders[1].FrontPen=Shadow;
  122.         list->Borders[1].DrawMode=JAM1;
  123.         list->Borders[1].Count=5;
  124.         list->Borders[1].XY=&(list->Vectors[1*5*2]);
  125.         list->Borders[1].NextBorder=NULL;
  126.  
  127.         list->Borders[2]=list->Borders[0];
  128.         list->Borders[2].FrontPen=Shadow;
  129.         list->Borders[2].NextBorder=&(list->Borders[3]);
  130.  
  131.         list->Borders[3]=list->Borders[1];
  132.         list->Borders[3].FrontPen=Highlight;
  133.  
  134.         FillTopLeft_Border(&(list->Borders[0]),Width,Height);
  135.         FillBottomRight_Border(&(list->Borders[1]),Width,Height);
  136.  
  137.         /*
  138.          * Set up the gadget
  139.          */
  140.         list->Gadget.NextGadget=*gad;    *gad=&(list->Gadget);
  141.         list->Gadget.LeftEdge=Left;
  142.         list->Gadget.TopEdge=Top;
  143.         list->Gadget.Width=Width;
  144.         list->Gadget.Height=Height;
  145.         list->Gadget.Flags=((Shadow==Highlight) ? GADGHCOMP : GADGHIMAGE);
  146.         list->Gadget.Activation=RELVERIFY;
  147.         list->Gadget.GadgetType=BOOLGADGET;
  148.         list->Gadget.GadgetRender=(APTR)&(list->Borders[0]);
  149.         list->Gadget.SelectRender=(APTR)&(list->Borders[2]);
  150.     }
  151.     return(list);
  152. }
  153.  
  154. /*
  155.  * Gadgets in the window and standard requesters...
  156.  */
  157. #define    GADGET_COPY    1
  158. #define    GADGET_REMOVE    2
  159. #define    GADGET_SHOW    3
  160. #define    GADGET_HELP    4
  161. #define    GADGET_ABOUT    5
  162. #define    FONT_DIR_ONE    6
  163. #define    FONT_DIR_TWO    7
  164. #define    OPEN_DIR_ONE    8
  165. #define    OPEN_DIR_TWO    9
  166.  
  167. /*
  168.  * These are the "stipped-down" structures needed for this
  169.  * example.
  170.  */
  171. struct FontList
  172. {
  173. struct    DisplayList    *Font_List;
  174. struct    DisplayList    *Size_List;
  175.     char        FontDirNameBuffer[256];
  176. };
  177.  
  178. struct TextGadget
  179. {
  180. struct    Gadget        Gadget;
  181. struct    IntuiText    IText;
  182. };
  183.  
  184. struct MyWindow
  185. {
  186. /*
  187.  * Pointer to the window all of this is in
  188.  */
  189. struct    Window        *Window;
  190.  
  191. /*
  192.  * The two "FontList" structures that will contain
  193.  * the font directory string gadgets and other such info...
  194.  */
  195. struct    FontList    Fonts[2];
  196.  
  197. /*
  198.  * This gives the active font side...  When the user selects
  199.  * an item on from one of the font or size lists, that side is
  200.  * made active.
  201.  */
  202.     SHORT        ActiveFont;
  203.  
  204. /*
  205.  * String gadgets and the borders and Info
  206.  */
  207. struct    Gadget        StringGadgets[2];
  208. struct    Border        StringBorders[2*2];
  209.     SHORT        StringVectors[4*5*2];
  210. struct    StringInfo    StringInfo[2];
  211.  
  212. /*
  213.  * The five action gadgets and the borders
  214.  */
  215. struct    TextGadget    ActionGadgets[5];
  216. struct    Border        ActionBorders[2*2];
  217.     SHORT        ActionVectors[2*5*2];
  218.  
  219. /*
  220.  * The two OPEN DIRECTORY gadget
  221.  */
  222. struct    TextGadget    OpenGadgets[2];
  223. struct    Border        OpenBorders[2*2];
  224.     SHORT        OpenVectors[2*5*2];
  225. struct    IntuiText    OpenText;    /* For the SELECT word */
  226.  
  227. /*
  228.  * For global details such as the dimple border
  229.  * and the display text we just have this simple
  230.  * gadget...
  231.  */
  232. struct    Gadget        DetailGadget;
  233. struct    Border        DetailBorders[3*2];
  234.     SHORT        DetailVectors[3*2*5*2];
  235.  
  236. /*
  237.  * The "RenderInfo" stuff is "stuffed" in here...
  238.  */
  239. struct    RenderInfo    *RenderInfo;
  240.  
  241. /*
  242.  * This is the TextAttr that was finally used
  243.  * for the window...  (In case of Fall-Back)
  244.  */
  245. struct    TextAttr    *RealTextAttr;
  246.  
  247. /*
  248.  * Global Undo buffer for string gadgets
  249.  */
  250.     char        UndoBuffer[256];
  251. };
  252.  
  253. /*
  254.  * The "default" font we might need for "FallBack"
  255.  */
  256. static char fontnam[11]="topaz.font";
  257. static struct TextAttr TOPAZ80={fontnam,8,0,FPF_ROMFONT};
  258.  
  259. #define    IN_BOX    1
  260. #define    OUT_BOX    2
  261.  
  262. /*
  263.  * This is the number of lines between the action gadgets...
  264.  */
  265. #define    LINES_BETWEEN    2
  266.  
  267. struct Detail_Defs
  268. {
  269.     SHORT    x,y,w,h;    /* Size and position */
  270.     SHORT    type;        /* IN_BOX or OUT_BOX */
  271. };
  272.  
  273. static struct Detail_Defs DetailStuff[3]=
  274. {
  275.     {  0, 34,398, 38,            IN_BOX},    /* Font Preview area    */
  276.     {190,  8, 18, 10+LINES_BETWEEN*2,    IN_BOX},    /* Dimple in...        */
  277.     {192,  9, 14,  8+LINES_BETWEEN*2,    OUT_BOX}    /* Dimple out...    */
  278. };
  279.  
  280. struct Action_Defs
  281. {
  282.     SHORT    y;        /* y position (x pos and size is fixed...) */
  283.     USHORT    GadgetID;    /* ID for this gadget */
  284.     short    Text;
  285. };
  286.  
  287. static short CopyNames[3]=
  288. {
  289.     TXT_CopyRightString,
  290.     TXT_CopyLeftString,
  291.     TXT_CopyGadgetString
  292. };
  293.  
  294. static struct Action_Defs AGadgetDef[5]=
  295. {
  296.     {13,            GADGET_COPY,    TXT_CopyGadgetString},
  297.     {13+LINES_BETWEEN,    GADGET_REMOVE,    TXT_RemoveGadgetString},
  298.     {13+LINES_BETWEEN*2,    GADGET_SHOW,    TXT_ShowGadgetString},
  299.     {32-LINES_BETWEEN,    GADGET_HELP,    TXT_HelpGadgetString},
  300.     {32,            GADGET_ABOUT,    TXT_AboutGadgetString}
  301. };
  302.  
  303. /*
  304.  * This routine centers a IntuiText string in the gadget.
  305.  *
  306.  * NOTE:  You *MUST* have the ITextFont set to a valid TextAttr
  307.  *        or else you *CRASH*
  308.  */
  309. void CenterTextInGadget(struct TextGadget *gad)
  310. {
  311.     gad->IText.LeftEdge=(((gad->Gadget.Width)-IntuiTextLength(&(gad->IText))) >> 1);
  312.     gad->IText.TopEdge=(((gad->Gadget.Height)-(gad->IText.ITextFont->ta_YSize)) >> 1);
  313. }
  314.  
  315. /*
  316.  * This routine is my simple, one-line user Alert plus a "Press to continue"
  317.  *
  318.  * Note that the text given should be 50 characters or less...
  319.  *
  320.  * Note also that this is using the "new" rule that text in
  321.  * alerts is TOPAZ80...
  322.  */
  323. void AlertUser(short TextID)
  324. {
  325. register    UBYTE    *c;
  326. register    char    *text;
  327.         char    RealBuffer[128];
  328.  
  329.     text=Get_String(TextID);
  330.  
  331.     c=RealBuffer;
  332.     *((USHORT *)c)=(80-strlen(text)) << 2;
  333.     c++;
  334.     c++;
  335.     *c++=14;
  336.     while (*text) *c++=*text++;
  337.     *c++=0;
  338.     *c++=1;
  339.     text=Get_String(TXT_PressButtonToContinue);
  340.     *((USHORT *)c)=(80-strlen(text)) << 2;
  341.     c++;
  342.     c++;
  343.     *c++=26;
  344.     while (*text) *c++=*text++;
  345.     *c++=0;
  346.     *c++=0;
  347.     DisplayAlert(RECOVERY_ALERT,RealBuffer,36);
  348. }
  349.  
  350. /*
  351.  * Example of a gadget that has more that one possible text string
  352.  * and how to "UpDate" the display
  353.  */
  354.  
  355. /*
  356.  * This routine changes the COPY gadget to point in the direction asked for.
  357.  *
  358.  * Direction Values are:  0 == Copy from left
  359.  *              1 == Copy from right
  360.  *              2 == No copy
  361.  */
  362. void ModifyCopy(struct MyWindow *my)
  363. {
  364. register    struct    TextGadget    *copyGad;
  365. register        char        *NewString;
  366.  
  367.     copyGad=&(my->ActionGadgets[0]);
  368.     if ((my->ActiveFont<0)||(my->ActiveFont>2)) my->ActiveFont=2;
  369.     NewString=Get_String(CopyNames[my->ActiveFont]);
  370.     if (copyGad->IText.IText!=NewString)
  371.     {
  372.         RemoveGadget(my->Window,&(copyGad->Gadget));
  373.         copyGad->IText.IText=NewString;
  374.         CenterTextInGadget(copyGad);
  375.         SetDrMd(my->Window->RPort,JAM1);
  376.         SetAPen(my->Window->RPort,0);
  377.         RectFill(my->Window->RPort,copyGad->Gadget.LeftEdge+2,copyGad->Gadget.TopEdge+1,copyGad->Gadget.LeftEdge+copyGad->Gadget.Width-5,copyGad->Gadget.TopEdge+copyGad->Gadget.Height-3);
  378.         AddGadget(my->Window,&(copyGad->Gadget),0);
  379.         RefreshGList(&(copyGad->Gadget),my->Window,NULL,1);
  380.     }
  381. }
  382.  
  383. /*
  384.  * This routine correctly frees any part of the MyWindow structure
  385.  * that is allocated.  This includes the Window, if it was open.
  386.  */
  387. void MyCloseWindow(struct MyWindow *my)
  388. {
  389.     if (my)
  390.     {
  391.         if (my->Window) CloseWindow(my->Window);
  392.         if (my->Fonts[0].Font_List) FreeListGadget(my->Fonts[0].Font_List);
  393.         if (my->Fonts[0].Size_List) FreeListGadget(my->Fonts[0].Size_List);
  394.         if (my->Fonts[1].Font_List) FreeListGadget(my->Fonts[1].Font_List);
  395.         if (my->Fonts[1].Size_List) FreeListGadget(my->Fonts[1].Size_List);
  396.         if (my->RenderInfo) CleanUp_RenderInfo(my->RenderInfo);
  397.         FreeMem(my,sizeof(struct MyWindow));
  398.     }
  399. }
  400.  
  401. /*
  402.  * Defines for the FALL_BACK flag...
  403.  */
  404. #define    NO_FALL_BACK    0
  405. #define    TRY_FALL_BACK    1
  406. #define    FALL_BACK_DONE    2
  407.  
  408. /*
  409.  * This routine allocates a MyWindow structure and puts together a window
  410.  * description plus gadgets for the FontMover.  It will also open this
  411.  * window if possible.  If it returns with a NULL, the open failed for some
  412.  * reason.  (Either not enough memory or too large a screen font)
  413.  */
  414. struct MyWindow *MyOpenWindow(ULONG Initial_IDCMP)
  415. {
  416. register        SHORT        loop;
  417. register        SHORT        y_plus;
  418. register        USHORT        highlight=GADGHIMAGE;
  419. register        short        TextGadget_X;
  420. register        short        TextGadget_Y;
  421. register        short        X_Extra;
  422. register        short        FallBack=NO_FALL_BACK;
  423. register    struct    TextAttr    *TextGadget_Attr;
  424. register    struct    MyWindow    *my;
  425. register    struct    Gadget        **gad;
  426. register    struct    RenderInfo    *ri;
  427.         struct    NewWindow    nw;
  428.  
  429.     while (FallBack<FALL_BACK_DONE) if (my=AllocMem(sizeof(struct MyWindow),MEMF_PUBLIC|MEMF_CLEAR))
  430.     {
  431.         /*
  432.          * Clear out the NewWindow structure and get ready to
  433.          * build the window we need...
  434.          */
  435.         memset((char *)&nw,0,sizeof(struct NewWindow));
  436.         gad=&(nw.FirstGadget);
  437.  
  438.         /*
  439.          * Get the rendering information...
  440.          */
  441.         if (my->RenderInfo=(ri=Get_RenderInfo(NULL)))
  442.         {
  443.             y_plus=ri->WindowTitle+ri->WindowTop;
  444.  
  445.             /*
  446.              * Check if we are in Fall-Back mode...
  447.              */
  448.             my->RealTextAttr=TextGadget_Attr=(FallBack ? &TOPAZ80 : &(ri->TextAttr));
  449.  
  450.             /*
  451.              * Quick, determine the text gadget sizes...
  452.              */
  453.             TextGadget_X=10+Max_Gadget_Length(TextGadget_Attr);
  454.             TextGadget_Y=4+(TextGadget_Attr->ta_YSize);
  455.  
  456.             /*
  457.              * Check if we need to used GADGHCOMP for those with single bit planes...
  458.              */
  459.             if (ri->Shadow==ri->Highlight) highlight=GADGHCOMP;
  460.  
  461.             /*
  462.              * Set up the COPY gadget state and the active font state.  (All in one ;-)
  463.              */
  464.             my->ActiveFont=2;
  465.  
  466.             /*
  467.              * Now, set up the two gadgets that let the user open
  468.              * the Directory Requester
  469.              */
  470.             my->OpenGadgets[0].IText.FrontPen=1;
  471.             my->OpenGadgets[0].IText.DrawMode=JAM1;
  472.             my->OpenGadgets[0].IText.ITextFont=TextGadget_Attr;
  473.             my->OpenGadgets[0].IText.IText="<";
  474.  
  475.             my->OpenGadgets[0].Gadget.NextGadget=*gad;    *gad=&(my->OpenGadgets[0].Gadget);
  476.             my->OpenGadgets[0].Gadget.TopEdge=1+y_plus+(((ri->FontSize)+4-TextGadget_Y) >> 1);
  477.             my->OpenGadgets[0].Gadget.Height=TextGadget_Y;
  478.             my->OpenGadgets[0].Gadget.Flags=highlight;
  479.             my->OpenGadgets[0].Gadget.Activation=RELVERIFY;
  480.             my->OpenGadgets[0].Gadget.GadgetType=BOOLGADGET;
  481.             my->OpenGadgets[0].Gadget.GadgetRender=(APTR)&(my->OpenBorders[0]);
  482.             my->OpenGadgets[0].Gadget.SelectRender=(APTR)&(my->OpenBorders[2]);
  483.             my->OpenGadgets[0].Gadget.GadgetText=&(my->OpenGadgets[0].IText);
  484.             my->OpenGadgets[0].Gadget.GadgetID=OPEN_DIR_ONE;
  485.             my->OpenGadgets[0].Gadget.UserData=(APTR)&(my->Fonts[0]);
  486.  
  487.             my->OpenGadgets[1]=my->OpenGadgets[0];
  488.             my->OpenGadgets[1].IText.IText=">";
  489.  
  490.             my->OpenGadgets[1].Gadget.NextGadget=*gad;    *gad=&(my->OpenGadgets[1].Gadget);
  491.             my->OpenGadgets[1].Gadget.GadgetText=&(my->OpenGadgets[1].IText);
  492.             my->OpenGadgets[1].Gadget.GadgetID=OPEN_DIR_TWO;
  493.             my->OpenGadgets[1].Gadget.UserData=(APTR)&(my->Fonts[1]);
  494.  
  495.             /*
  496.              * Find the widest of the two...
  497.              */
  498.             my->OpenGadgets[0].Gadget.Width=IntuiTextLength(&(my->OpenGadgets[0].IText))+6;
  499.             my->OpenGadgets[1].Gadget.Width=IntuiTextLength(&(my->OpenGadgets[1].IText))+6;
  500.  
  501.             if ((my->OpenGadgets[0].Gadget.Width) > (my->OpenGadgets[1].Gadget.Width))
  502.             {
  503.                 my->OpenGadgets[1].Gadget.Width=my->OpenGadgets[0].Gadget.Width;
  504.             }
  505.             else
  506.             {
  507.                 my->OpenGadgets[0].Gadget.Width=my->OpenGadgets[1].Gadget.Width;
  508.             }
  509.  
  510.             /*
  511.              * Center the '<' and '>' in the gadgets
  512.              */
  513.             CenterTextInGadget(&(my->OpenGadgets[0]));
  514.             CenterTextInGadget(&(my->OpenGadgets[1]));
  515.  
  516.             /*
  517.              * Add in the text between the gadgets
  518.              */
  519.             my->OpenText=my->OpenGadgets[0].IText;
  520.             my->OpenGadgets[0].IText.NextText=&(my->OpenText);
  521.             my->OpenText.IText=Get_String(TXT_DirSelectGadget);
  522.  
  523.             /*
  524.              * Make sure that the text will fit between the gadgets...
  525.              */
  526.             TextGadget_X-=1;
  527.             my->OpenText.LeftEdge=-100;    /* Make sure we do this atleast once */
  528.             while (my->OpenText.LeftEdge < (my->OpenGadgets[0].Gadget.Width+2))
  529.             {
  530.                 TextGadget_X+=1;
  531.  
  532.                 /*
  533.                  * Adjust the list gadget widths if we grow too large
  534.                  * with the gadgets.
  535.                  *
  536.                  * NOTE:  85 is the LARGEST the adjustment value can be
  537.                  *        otherwise some gadgets will run into each other.
  538.                  *        Smaller values will cause more expansion.
  539.                  */
  540.                 X_Extra=((TextGadget_X > 74) ? ((TextGadget_X-74) << 1) : 0);
  541.  
  542.                 /*
  543.                  * Calculate new values for X positions of the gadgets
  544.                  * and the text between them...
  545.                  */
  546.                 my->OpenText.LeftEdge=(my->OpenGadgets[0].Gadget.Width) +
  547.                     (
  548.                     (
  549.                         (my->OpenGadgets[1].Gadget.LeftEdge=212-(my->OpenGadgets[1].Gadget.Width)+TextGadget_X+((ri->WindowLeft)*2)+X_Extra) -
  550.                         (my->OpenGadgets[0].Gadget.LeftEdge=186+((ri->WindowLeft)*2)+X_Extra) -
  551.                         (my->OpenGadgets[0].Gadget.Width) -
  552.                         IntuiTextLength(&(my->OpenText))
  553.                     ) >> 1
  554.                     );
  555.             }
  556.  
  557.             /*
  558.              * Set up borders for the string gadgets (One set for both gadgets...)
  559.              */
  560.             my->StringBorders[0].LeftEdge=-5;
  561.             my->StringBorders[0].TopEdge=-3;
  562.             my->StringBorders[0].FrontPen=ri->Highlight;
  563.             my->StringBorders[0].DrawMode=JAM1;
  564.             my->StringBorders[0].Count=5;
  565.             my->StringBorders[0].XY=&(my->StringVectors[0*5*2]);
  566.             my->StringBorders[0].NextBorder=&(my->StringBorders[1]);
  567.  
  568.             my->StringBorders[1]=my->StringBorders[0];
  569.             my->StringBorders[1].FrontPen=ri->Shadow;
  570.             my->StringBorders[1].XY=&(my->StringVectors[1*5*2]);
  571.             my->StringBorders[1].NextBorder=&(my->StringBorders[2]);
  572.  
  573.             my->StringBorders[2].LeftEdge=-3;
  574.             my->StringBorders[2].TopEdge=-2;
  575.             my->StringBorders[2].FrontPen=ri->Shadow;
  576.             my->StringBorders[2].DrawMode=JAM1;
  577.             my->StringBorders[2].Count=5;
  578.             my->StringBorders[2].XY=&(my->StringVectors[2*5*2]);
  579.             my->StringBorders[2].NextBorder=&(my->StringBorders[3]);
  580.  
  581.             my->StringBorders[3]=my->StringBorders[2];
  582.             my->StringBorders[3].FrontPen=ri->Highlight;
  583.             my->StringBorders[3].XY=&(my->StringVectors[3*5*2]);
  584.             my->StringBorders[3].NextBorder=NULL;
  585.  
  586.             FillTopLeft_Border(&(my->StringBorders[0]),182+X_Extra,6+ri->FontSize);
  587.             FillBottomRight_Border(&(my->StringBorders[1]),182+X_Extra,6+ri->FontSize);
  588.             FillTopLeft_Border(&(my->StringBorders[2]),178+X_Extra,4+ri->FontSize);
  589.             FillBottomRight_Border(&(my->StringBorders[3]),178+X_Extra,4+ri->FontSize);
  590.  
  591.             /*
  592.              * Set up borders for the action gadgets (One set for all gadgets...)
  593.              */
  594.             my->ActionBorders[0].FrontPen=ri->Highlight;
  595.             my->ActionBorders[0].DrawMode=JAM1;
  596.             my->ActionBorders[0].Count=5;
  597.             my->ActionBorders[0].XY=&(my->ActionVectors[0*5*2]);
  598.             my->ActionBorders[0].NextBorder=&(my->ActionBorders[1]);
  599.  
  600.             my->ActionBorders[1].FrontPen=ri->Shadow;
  601.             my->ActionBorders[1].DrawMode=JAM1;
  602.             my->ActionBorders[1].Count=5;
  603.             my->ActionBorders[1].XY=&(my->ActionVectors[1*5*2]);
  604.             my->ActionBorders[1].NextBorder=NULL;
  605.  
  606.             my->ActionBorders[2]=my->ActionBorders[0];
  607.             my->ActionBorders[2].FrontPen=ri->Shadow;
  608.             my->ActionBorders[2].NextBorder=&(my->ActionBorders[3]);
  609.  
  610.             my->ActionBorders[3]=my->ActionBorders[1];
  611.             my->ActionBorders[3].FrontPen=ri->Highlight;
  612.  
  613.             FillTopLeft_Border(&(my->ActionBorders[0]),TextGadget_X,TextGadget_Y);
  614.             FillBottomRight_Border(&(my->ActionBorders[1]),TextGadget_X,TextGadget_Y);
  615.  
  616.             /*
  617.              * Set up borders for the "open" gadgets (One set for all gadgets...)
  618.              */
  619.             my->OpenBorders[0]=my->ActionBorders[0];
  620.             my->OpenBorders[0].XY=&(my->OpenVectors[0*5*2]);
  621.             my->OpenBorders[0].NextBorder=&(my->OpenBorders[1]);
  622.  
  623.             my->OpenBorders[1]=my->ActionBorders[1];
  624.             my->OpenBorders[1].XY=&(my->OpenVectors[1*5*2]);
  625.  
  626.             my->OpenBorders[2]=my->OpenBorders[0];
  627.             my->OpenBorders[2].FrontPen=ri->Shadow;
  628.             my->OpenBorders[2].NextBorder=&(my->OpenBorders[3]);
  629.  
  630.             my->OpenBorders[3]=my->OpenBorders[1];
  631.             my->OpenBorders[3].FrontPen=ri->Highlight;
  632.  
  633.             FillTopLeft_Border(&(my->OpenBorders[0]),my->OpenGadgets[0].Gadget.Width,TextGadget_Y);
  634.             FillBottomRight_Border(&(my->OpenBorders[1]),my->OpenGadgets[0].Gadget.Width,TextGadget_Y);
  635.  
  636.             /*
  637.              * Set up borders for the display "details"
  638.              */
  639.             {
  640.             register    struct    Border    *tmp;
  641.  
  642.                 tmp=&(my->DetailBorders[0]);
  643.  
  644.                 for (loop=0;loop<3;loop++)
  645.                 {
  646.                     tmp->LeftEdge=DetailStuff[loop].x+(loop ? X_Extra : 0);
  647.                     tmp->TopEdge=DetailStuff[loop].y+(loop ? 0 : (5*TextGadget_Y));
  648.                     tmp->FrontPen=((DetailStuff[loop].type==OUT_BOX) ? ri->Highlight : ri->Shadow);
  649.                     tmp->DrawMode=JAM1;
  650.                     tmp->Count=5;
  651.                     tmp->XY=&(my->DetailVectors[loop*2*5*2]);
  652.                     tmp->NextBorder=&(tmp[1]);
  653.  
  654.                     FillTopLeft_Border(tmp,DetailStuff[loop].w+TextGadget_X+(loop ? 0 : (2*X_Extra)),DetailStuff[loop].h+((loop ? 3 : 1)*TextGadget_Y));
  655.  
  656.                     tmp=&(tmp[1]);
  657.  
  658.                     tmp->LeftEdge=DetailStuff[loop].x+(loop ? X_Extra : 0);
  659.                     tmp->TopEdge=DetailStuff[loop].y+(loop ? 0 : (5*TextGadget_Y));
  660.                     tmp->FrontPen=((DetailStuff[loop].type==OUT_BOX) ? ri->Shadow : ri->Highlight);
  661.                     tmp->DrawMode=JAM1;
  662.                     tmp->Count=5;
  663.                     tmp->XY=&(my->DetailVectors[((loop*2)+1)*5*2]);
  664.                     tmp->NextBorder=&(tmp[1]);
  665.  
  666.                     FillBottomRight_Border(tmp,DetailStuff[loop].w+TextGadget_X+(loop ? 0 : (2*X_Extra)),DetailStuff[loop].h+((loop ? 3 : 1)*TextGadget_Y));
  667.  
  668.                     tmp=&(tmp[1]);
  669.                 }
  670.  
  671.                 tmp[-1].NextBorder=NULL;
  672.             }
  673.  
  674.             /*
  675.              * Now, set up the string gadgets...  We know what the title bar
  676.              * size is and what the font size will be for the gadgets.
  677.              */
  678.             my->StringGadgets[0].NextGadget=*gad;    *gad=&(my->StringGadgets[0]);
  679.             my->StringGadgets[0].LeftEdge=5+((ri->WindowLeft)*2);
  680.             my->StringGadgets[0].TopEdge=3+y_plus;
  681.             my->StringGadgets[0].Width=172+X_Extra;
  682.             my->StringGadgets[0].Height=ri->FontSize;
  683.             my->StringGadgets[0].Flags=GADGHCOMP;
  684.             my->StringGadgets[0].Activation=RELVERIFY;
  685.             my->StringGadgets[0].GadgetType=STRGADGET;
  686.             my->StringGadgets[0].GadgetRender=(APTR)&(my->StringBorders[0]);
  687.             my->StringGadgets[0].SpecialInfo=(APTR)&(my->StringInfo[0]);
  688.             my->StringGadgets[0].GadgetID=FONT_DIR_ONE;
  689.  
  690.             my->StringGadgets[1]=my->StringGadgets[0];
  691.             my->StringGadgets[1].NextGadget=*gad;    *gad=&(my->StringGadgets[1]);
  692.             my->StringGadgets[1].LeftEdge=221+TextGadget_X+((ri->WindowLeft)*2)+X_Extra;
  693.             my->StringGadgets[1].SpecialInfo=(APTR)&(my->StringInfo[1]);
  694.             my->StringGadgets[1].GadgetID=FONT_DIR_TWO;
  695.  
  696.             my->StringInfo[0].Buffer=my->Fonts[0].FontDirNameBuffer;
  697.             my->StringInfo[0].UndoBuffer=my->UndoBuffer;
  698.             my->StringInfo[0].MaxChars=250;
  699.  
  700.             my->StringInfo[1].Buffer=my->Fonts[1].FontDirNameBuffer;
  701.             my->StringInfo[1].UndoBuffer=my->UndoBuffer;
  702.             my->StringInfo[1].MaxChars=250;
  703.  
  704.             y_plus+=ri->FontSize;
  705.  
  706.             /*
  707.              * Set up a fake gadget that will hold the
  708.              * display details such as the boxes and borders
  709.              */
  710.             my->DetailGadget.NextGadget=*gad;    *gad=&(my->DetailGadget);
  711.             my->DetailGadget.LeftEdge=((ri->WindowLeft)*2);
  712.             my->DetailGadget.TopEdge=y_plus;
  713.             my->DetailGadget.Flags=GADGHNONE;
  714.             my->DetailGadget.GadgetType=BOOLGADGET;
  715.             my->DetailGadget.GadgetRender=(APTR)&(my->DetailBorders[0]);
  716.  
  717.             /*
  718.              * Now do the action gadgets...
  719.              */
  720.             for (loop=0;loop<5;loop++)
  721.             {
  722.                 my->ActionGadgets[loop].Gadget.NextGadget=*gad;    *gad=&(my->ActionGadgets[loop].Gadget);
  723.                 my->ActionGadgets[loop].Gadget.LeftEdge=199+((ri->WindowLeft)*2)+X_Extra;
  724.                 my->ActionGadgets[loop].Gadget.TopEdge=AGadgetDef[loop].y+y_plus+loop*TextGadget_Y;
  725.                 my->ActionGadgets[loop].Gadget.Width=TextGadget_X;
  726.                 my->ActionGadgets[loop].Gadget.Height=TextGadget_Y;
  727.                 my->ActionGadgets[loop].Gadget.Flags=highlight;
  728.                 my->ActionGadgets[loop].Gadget.Activation=RELVERIFY;
  729.                 my->ActionGadgets[loop].Gadget.GadgetType=BOOLGADGET;
  730.                 my->ActionGadgets[loop].Gadget.GadgetRender=(APTR)&(my->ActionBorders[0]);
  731.                 my->ActionGadgets[loop].Gadget.SelectRender=(APTR)&(my->ActionBorders[2]);
  732.                 my->ActionGadgets[loop].Gadget.GadgetText=&(my->ActionGadgets[loop].IText);
  733.                 my->ActionGadgets[loop].Gadget.GadgetID=AGadgetDef[loop].GadgetID;
  734.  
  735.                 my->ActionGadgets[loop].IText.FrontPen=1;
  736.                 my->ActionGadgets[loop].IText.BackPen=0;
  737.                 my->ActionGadgets[loop].IText.DrawMode=JAM1;
  738.                 my->ActionGadgets[loop].IText.ITextFont=TextGadget_Attr;
  739.                 my->ActionGadgets[loop].IText.IText=Get_String(AGadgetDef[loop].Text);
  740.                 CenterTextInGadget(&(my->ActionGadgets[loop]));
  741.             }
  742.  
  743.             /*
  744.              * Get the four list gadgets set up...
  745.              */
  746.             {
  747.             register    short    tmpExtra;
  748.  
  749.                 tmpExtra=(X_Extra >> 1);
  750.                 my->Fonts[0].Font_List=InitListGadget(gad,ri->Highlight,ri->Shadow,((ri->WindowLeft)*2),8+y_plus,130+tmpExtra,24+5*TextGadget_Y);
  751.                 my->Fonts[0].Size_List=InitListGadget(gad,ri->Highlight,ri->Shadow,134+((ri->WindowLeft)*2)+tmpExtra,8+y_plus,48+X_Extra-tmpExtra,24+5*TextGadget_Y);
  752.                 my->Fonts[1].Font_List=InitListGadget(gad,ri->Highlight,ri->Shadow,216+TextGadget_X+X_Extra+((ri->WindowLeft)*2),8+y_plus,130+tmpExtra,24+5*TextGadget_Y);
  753.                 my->Fonts[1].Size_List=InitListGadget(gad,ri->Highlight,ri->Shadow,350+TextGadget_X+X_Extra+((ri->WindowLeft)*2)+tmpExtra,8+y_plus,48+X_Extra-tmpExtra,24+5*TextGadget_Y);
  754.             }
  755.  
  756.             /*
  757.              * Set up the NewWindow structure now that the gadgets are done...
  758.              */
  759.             nw.LeftEdge=0;
  760.             nw.TopEdge=0;
  761.             nw.Width=398+((ri->WindowLeft+ri->WindowRight)*2)+TextGadget_X+(2*X_Extra);
  762.             nw.Height=72+y_plus+((ri->WindowBottom)*2)+(6*TextGadget_Y);
  763.             nw.DetailPen=-1;
  764.             nw.BlockPen=-1;
  765.             nw.IDCMPFlags=Initial_IDCMP;
  766.             nw.Flags=WINDOWDRAG|WINDOWDEPTH|WINDOWCLOSE|SMART_REFRESH|NOCAREREFRESH|ACTIVATE;
  767.             nw.Title=Get_String(TXT_Window_Title);
  768.             nw.MinWidth=nw.Width;
  769.             nw.MinHeight=nw.Height;
  770.             nw.MaxWidth=nw.Width;
  771.             nw.MaxHeight=nw.Height;
  772.             nw.Type=WBENCHSCREEN;
  773.  
  774.             /*
  775.              * Now, check if all it a go for opening the window
  776.              */
  777.             if (    (my->Fonts[0].Font_List)
  778.                  &&    (my->Fonts[0].Size_List)
  779.                  &&    (my->Fonts[1].Font_List)
  780.                  &&    (my->Fonts[1].Size_List)    ) my->Window=OpenWindow(&nw);
  781.         }
  782.  
  783.         /*
  784.          * If we did not get a window, free everything and return NULL
  785.          */
  786.         if (!(my->Window))
  787.         {
  788.             MyCloseWindow(my);
  789.             my=NULL;
  790.             FallBack+=1;
  791.         }
  792.         else FallBack=FALL_BACK_DONE;
  793.     }
  794.     else FallBack=FALL_BACK_DONE;
  795.  
  796.     if (!my) AlertUser(TXT_WindowOpenError);
  797.  
  798.     return(my);
  799. }
  800.  
  801. /*
  802.  * Code to "Make this work"
  803.  */
  804. void DoFontMover(struct MyWindow *mywin)
  805. {
  806. register        short        ExitFlag=FALSE;
  807. register    struct    IntuiMessage    *msg;
  808. register    struct    Gadget        *gad;
  809.  
  810.     while (!ExitFlag)
  811.     {
  812.         WaitPort(mywin->Window->UserPort);
  813.         while (msg=(struct IntuiMessage *)GetMsg(mywin->Window->UserPort))
  814.         {
  815.             if (msg->Class==CLOSEWINDOW) ExitFlag=TRUE;
  816.             else if (msg->Class==GADGETUP)
  817.             {
  818.                 if (gad=(struct Gadget *)(msg->IAddress))
  819.                 {
  820.                     if (gad->GadgetID==GADGET_COPY)
  821.                     {
  822.                         mywin->ActiveFont-=1;
  823.                         ModifyCopy(mywin);
  824.                     }
  825.                 }
  826.             }
  827.             ReplyMsg((struct Message *)msg);
  828.         }
  829.     }
  830. }
  831.  
  832. /*
  833.  * Main...
  834.  *
  835.  * This just opens everything that will be needed...
  836.  */
  837. void main(void)
  838. {
  839. register    struct    MyWindow    *MyWindow;
  840.  
  841.     if (IntuitionBase=OpenLibrary("intuition.library",33L))
  842.     {
  843.         if (LayersBase=OpenLibrary("layers.library",33L))
  844.         {
  845.             if (GfxBase=OpenLibrary("graphics.library",33L))
  846.             {
  847.                 if (MyWindow=MyOpenWindow(GADGETUP|CLOSEWINDOW))
  848.                 {
  849.                     DoFontMover(MyWindow);
  850.                     MyCloseWindow(MyWindow);
  851.                 }
  852.                 CloseLibrary(GfxBase);
  853.             }
  854.             else AlertUser(TXT_OpenGraphicsError);
  855.             CloseLibrary(LayersBase);
  856.         }
  857.         else AlertUser(TXT_OpenLayersError);
  858.         CloseLibrary(IntuitionBase);
  859.     }
  860. }
  861.